package com.zxshhy.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.zxshhy.BalanceServiceFeign;
import com.zxshhy.StorageServiceFeign;
import com.zxshhy.config.RabbitMqConfig;
import com.zxshhy.entity.Order;
import com.zxshhy.entity.OrderStatus;
import com.zxshhy.mapper.OrderMapper;
import com.zxshhy.service.OrderService;
import com.zxshhy.util.UUIDGenerator;
import com.zxshhy.vo.OrderVo;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

@Slf4j
@Service
public class OrderServiceImpl implements OrderService {
    @Resource
    private OrderMapper orderMapper;
    @Resource
    private StorageServiceFeign storageServiceFeign;
    @Resource
    private BalanceServiceFeign balanceServiceFeign;
    @Resource
    private RabbitTemplate rabbitTemplate;

    /**
     * 采用二阶段提交XA，AT强一致性实现分布式事务
     * @param orderVo
     * @return
     */
    @Transactional
    @GlobalTransactional(name="createOrder",rollbackFor=Exception.class)
    @Override
    public Order saveOrder(OrderVo orderVo) {
        Order order = new Order();
        BeanUtils.copyProperties(orderVo,order);
        Long orderId = UUIDGenerator.generateUUID();
        order.setId(orderId);
        int count = orderMapper.insert(order);
        //扣减库存
        storageServiceFeign.deduct(orderVo.getCommodityCode(), orderVo.getCount());
        //扣减余额
        boolean debit= balanceServiceFeign.debit(orderVo.getUserId(), orderVo.getMoney());
        log.info("\n扣减余额结果：{}",debit);
        //更新订单
        Integer updateOrderRecord = orderMapper.updateOrderStatus(order.getId(), OrderStatus.SUCCESS.getValue());
        log.info("更新订单id:{} {}", order.getId(), updateOrderRecord > 0 ? "成功" : "失败");
        return count>0?order:null;
    }

    /**
     * 采用消息队列实现分布式事务
     * @param orderVo
     * @return
     */
    @Override
    public Order saveOrderByMQ(OrderVo orderVo) {
        Order order = new Order();
        BeanUtils.copyProperties(orderVo,order);
        //获取全局唯一订单号  测试使用
        Long orderId = UUIDGenerator.generateUUID();
        order.setId(orderId);
        int count = orderMapper.insert(order);
        if(count>0){
            //扣减库存
            log.info("订单创建成功，发送扣减库存MQ消息");
            CorrelationData storageCorrelationData = new CorrelationData(JSONObject.toJSONString(order));
            rabbitTemplate.convertAndSend(RabbitMqConfig.ZXSHHY_DIRECT_EXCHANGE,RabbitMqConfig.ZXSHHY_STORAGE_ROUTINGKEY,JSONObject.toJSONString(order),storageCorrelationData);
            //扣减余额
            log.info("订单创建成功，发送扣减余额MQ消息");
            CorrelationData balanceCorrelationData = new CorrelationData(JSONObject.toJSONString(order));
            rabbitTemplate.convertAndSend(RabbitMqConfig.ZXSHHY_DIRECT_EXCHANGE,RabbitMqConfig.ZXSHHY_BALANCE_ROUTINGKEY,JSONObject.toJSONString(order),balanceCorrelationData);
        }
        return count>0?order:null;
    }

    @Override
    public Order getOrderById(String orderId) {
        Order order = orderMapper.selectById(orderId);
        return order;
    }
}
